package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.content.mapper.TeachplanMapper;
import com.xuecheng.content.mapper.TeachplanMediaMapper;
import com.xuecheng.content.model.dto.BindTeachplanMediaDto;
import com.xuecheng.content.model.dto.SaveTeachplanDto;
import com.xuecheng.content.model.dto.TeachplanDto;
import com.xuecheng.content.model.po.Teachplan;
import com.xuecheng.content.model.po.TeachplanMedia;
import com.xuecheng.content.service.TeachplanService;
import com.xuecheng.exception.XueChengPlusException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class TeachplanServiceImpl implements TeachplanService {

    @Autowired
    TeachplanMapper teachplanMapper;

    @Autowired
    TeachplanMediaMapper teachplanMediaMapper;

    @Override
    public List<TeachplanDto> findTeachplanTree(long courseId) {
        return teachplanMapper.selectTreeNodes(courseId);
    }

    /**
     * 保存teachplan
     *
     * @param teachplanDto teachplan dto
     */
    @Transactional
    @Override
    public void saveTeachplan(SaveTeachplanDto teachplanDto) {
        // 通过id判断新增还是修改
        Long id = teachplanDto.getId();
        if (id == null) {
            // 新增
            Teachplan teachplan = new Teachplan();
            BeanUtils.copyProperties(teachplanDto,teachplan);
            teachplan.setCreateDate(LocalDateTime.now());
            // 确定排序字段
            // select count(1) from teachplan where course_id = 117 and parent = 268
            Long parentId = teachplanDto.getParentid();
            Long courseId = teachplanDto.getCourseId();
            Integer count = getTeachplanCount(parentId, courseId);
            teachplan.setOrderby(count+1);

            int flag = teachplanMapper.insert(teachplan);
            if (flag <= 0) {
                XueChengPlusException.cast("新增失败！");
            }

        }else {
            // 修改
            Teachplan teachplan = teachplanMapper.selectById(id);
            BeanUtils.copyProperties(teachplanDto, teachplan);
            teachplan.setChangeDate(LocalDateTime.now());
            int flag = teachplanMapper.updateById(teachplan);
            if (flag <= 0) {
                XueChengPlusException.cast("修改失败！");
            }
        }
    }

    /**
     * 删除课程计划
     * @param teachplanId
     */
    @Override
    public void deleteTeachplan(Long teachplanId) {
        // 判断课程计划是否为空
        if (teachplanId == null) {
            XueChengPlusException.cast("课程计划为空！");
        }
        // 查找课程计划
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        Integer teachplanGrade = teachplan.getGrade();
        // 如果是大章节
        if (teachplanGrade == 1) {
            // 判断是否有小章节
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            // select * from teachplan where parentid = {当前章计划id}
            queryWrapper.eq(Teachplan::getParentid, teachplanId);
            // 获取一下查询的条目数
            Integer count = teachplanMapper.selectCount(queryWrapper);
            // 如果当前章下还有小节，则抛异常
            if (count > 0)
                XueChengPlusException.cast("课程计划信息还有子级信息，无法操作");
            teachplanMapper.deleteById(teachplanId);
        }else {
            // 课程计划为节
            teachplanMapper.deleteById(teachplanId);
            LambdaQueryWrapper<TeachplanMedia> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(TeachplanMedia::getTeachplanId, teachplanId);
            // 删除视频信息
            teachplanMediaMapper.delete(queryWrapper);
        }

    }

    /**
     * 上移课程计划
     *
     * @param teachplanId
     */
    @Override
    public void moveUpTeachplan(Long teachplanId) {
        // 找到这个章节
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if (teachplan == null) {
            XueChengPlusException.cast("没有此章节！");
        }
        // 判断是大章节还是小章节
        Integer grade = teachplan.getGrade();
        if (grade == 1) {
            // 拿到orderby
            Integer orderby = teachplan.getOrderby();
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getGrade, 1)
                    .eq(Teachplan::getCourseId, teachplan.getCourseId())
                    .lt(Teachplan::getOrderby, orderby)// 小于这个orderBy
                    .orderByDesc(Teachplan::getOrderby)
                    .last("LIMIT 1");
            // 找到上一个Teachplan
            Teachplan UpTeachplan = teachplanMapper.selectOne(queryWrapper);
            exchangeTeachplan(teachplan, UpTeachplan);
        }else {
            // 拿到orderby
            Integer orderby = teachplan.getOrderby();
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getParentid, teachplan.getParentid())
                    .lt(Teachplan::getOrderby, orderby)
                    .orderByDesc(Teachplan::getOrderby)
                    .last("LIMIT 1");
            Teachplan UpTeachplan = teachplanMapper.selectOne(queryWrapper);
            exchangeTeachplan(teachplan, UpTeachplan);
        }

    }
    /**
     * 下移课程计划
     *
     * @param teachplanId
     */
    @Override
    public void moveDownTeachplan(Long teachplanId) {
        // 找到这个章节
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if (teachplan == null) {
            XueChengPlusException.cast("没有此章节！");
        }
        // 判断是大章节还是小章节
        Integer grade = teachplan.getGrade();
        if (grade == 1) {
            // 拿到orderby
            Integer orderby = teachplan.getOrderby();
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getGrade, 1)
                    .eq(Teachplan::getCourseId, teachplan.getCourseId())
                    .gt(Teachplan::getOrderby, orderby)// 小于这个orderBy
                    .orderByAsc(Teachplan::getOrderby)
                    .last("LIMIT 1");
            // 找到上一个Teachplan
            Teachplan UpTeachplan = teachplanMapper.selectOne(queryWrapper);
            exchangeTeachplan(teachplan, UpTeachplan);
        }else {
            // 拿到orderby
            Integer orderby = teachplan.getOrderby();
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getParentid, teachplan.getParentid())
                    .gt(Teachplan::getOrderby, orderby)
                    .orderByAsc(Teachplan::getOrderby)
                    .last("LIMIT 1");
            Teachplan UpTeachplan = teachplanMapper.selectOne(queryWrapper);
            exchangeTeachplan(teachplan, UpTeachplan);
        }

    }
    /**
     * 交换OrderBy
     * @param teachplan
     * @param UpTeachplan
     */
    private void exchangeTeachplan(Teachplan teachplan, Teachplan UpTeachplan) {
        if (UpTeachplan == null) {
            XueChengPlusException.cast("已到顶端/末端，无法进行移动！");
        }
        Integer upTeachplanOrderby = UpTeachplan.getOrderby();
        Integer orderby = teachplan.getOrderby();
        UpTeachplan.setOrderby(orderby);
        teachplan.setOrderby(upTeachplanOrderby);
        teachplanMapper.updateById(teachplan);
        teachplanMapper.updateById(UpTeachplan);
    }

    private Integer getTeachplanCount(Long parentId, Long courseId) {
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(Teachplan::getCourseId, courseId)
                        .eq(Teachplan::getParentid, parentId);
        return teachplanMapper.selectCount(queryWrapper);
    }

    /**
     * 关联媒资与课程计划
     *
     * @param bindTeachplanMediaDto
     * @return {@link TeachplanMedia}
     */
    @Transactional
    @Override
    public TeachplanMedia associationMedia(BindTeachplanMediaDto bindTeachplanMediaDto) {
        //教学计划id
        Long teachplanId = bindTeachplanMediaDto.getTeachplanId();
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if(teachplan == null){
            XueChengPlusException.cast("教学计划不存在");
        }
        Integer grade = teachplan.getGrade();
        if(grade != 2){
            XueChengPlusException.cast("只允许第二级教学计划绑定媒资文件");
        }
        //课程id
        Long courseId = teachplan.getCourseId();

        //先删除原来该教学计划绑定的媒资
        teachplanMediaMapper.delete(
                new LambdaQueryWrapper<TeachplanMedia>()
                        .eq(TeachplanMedia::getTeachplanId,teachplanId)
        );

        //再添加教学计划与媒资的绑定关系
        TeachplanMedia teachplanMedia = new TeachplanMedia();
        teachplanMedia.setCourseId(courseId);
        teachplanMedia.setTeachplanId(teachplanId);
        teachplanMedia.setMediaFilename(bindTeachplanMediaDto.getFileName());
        teachplanMedia.setMediaId(bindTeachplanMediaDto.getMediaId());
        teachplanMedia.setCreateDate(LocalDateTime.now());
        teachplanMediaMapper.insert(teachplanMedia);
        return teachplanMedia;
    }

    /**
     * 解除教学计划绑定媒资
     *
     * @param teachplanId
     * @param mediaId
     */
    @Transactional
    @Override
    public void deleteAssociationMedia(Long teachplanId, String mediaId) {
        //教学计划id判断教学计划是否存在
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if(teachplan == null){
            XueChengPlusException.cast("教学计划不存在");
        }
        teachplanMediaMapper.delete(
                new LambdaQueryWrapper<TeachplanMedia>()
                        .eq(TeachplanMedia::getTeachplanId, teachplanId)
                        .eq(TeachplanMedia::getMediaId, mediaId)
        );
    }

    /**
     * 根据课程计划id查询课程计划
     * @param teachplanId
     * @return
     */
    @Override
    public Teachplan getTeachplanById(Long teachplanId) {
        return teachplanMapper.selectById(teachplanId);
    }
}